package com.leo;

import com.jfoenix.controls.JFXTextField;
import com.jfoenix.controls.JFXTreeTableColumn;
import com.jfoenix.controls.JFXTreeTableView;
import com.jfoenix.controls.RecursiveTreeItem;
import com.jfoenix.controls.cells.editors.TextFieldEditorBuilder;
import com.jfoenix.controls.cells.editors.base.GenericEditableTreeTableCell;
import com.jfoenix.controls.datamodels.treetable.RecursiveTreeObject;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.layout.AnchorPane;
import javafx.stage.Stage;

import java.net.URL;

/**
 * @ClassName JFXTreeTableColumnDemo
 * @Description
 * @Author wangss
 * @date 2020.11.26 14:10
 * @Version 1.0
 */
public class JFXTreeTableColumnDemo extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        JFXTreeTableColumn<User, String> deptColumn = new JFXTreeTableColumn<>("Department");
        deptColumn.setPrefWidth(150);
        deptColumn.setCellValueFactory((TreeTableColumn.CellDataFeatures<User, String> param) -> {
            if (deptColumn.validateValue(param)) {
                return param.getValue().getValue().department;
            } else {
                return deptColumn.getComputedValue(param);
            }
        });

        JFXTreeTableColumn<User, String> empColumn = new JFXTreeTableColumn<>("Employee");
        empColumn.setPrefWidth(150);
        empColumn.setCellValueFactory((TreeTableColumn.CellDataFeatures<User, String> param) -> {
            if (empColumn.validateValue(param)) {
                return param.getValue().getValue().userName;
            } else {
                return empColumn.getComputedValue(param);
            }
        });

        JFXTreeTableColumn<User, String> ageColumn = new JFXTreeTableColumn<>("Age");
        ageColumn.setPrefWidth(150);
        ageColumn.setCellValueFactory((TreeTableColumn.CellDataFeatures<User, String> param) -> {
            if (ageColumn.validateValue(param)) {
                return param.getValue().getValue().age;
            } else {
                return ageColumn.getComputedValue(param);
            }
        });

        ageColumn.setCellFactory(param -> null);
        ageColumn.setCellFactory(param -> new GenericEditableTreeTableCell<>(new TextFieldEditorBuilder()));
        ageColumn.setOnEditCommit((TreeTableColumn.CellEditEvent<User, String> t) -> {
            ((User) t.getTreeTableView().getTreeItem(t.getTreeTablePosition().getRow()).getValue()).age
                    .set(t.getNewValue());
        });

        empColumn.setCellFactory((TreeTableColumn<User, String> param) -> new GenericEditableTreeTableCell<>(new TextFieldEditorBuilder()));
        empColumn.setOnEditCommit((TreeTableColumn.CellEditEvent<User, String> t) -> {
            ((User) t.getTreeTableView().getTreeItem(t.getTreeTablePosition().getRow()).getValue())
                    .userName.set(t.getNewValue());
        });

        deptColumn.setCellFactory(param ->
                new GenericEditableTreeTableCell<User, String>(new TextFieldEditorBuilder()));
        deptColumn.setOnEditCommit((TreeTableColumn.CellEditEvent<User, String> t) -> {
            ((User) t.getTreeTableView().getTreeItem(t.getTreeTablePosition().getRow()).getValue()).department.
                    set(t.getNewValue());
        });


        // data
        ObservableList<User> users = FXCollections.observableArrayList();
        users.add(new User("Computer Department", "23", "CD 1"));
        users.add(new User("Sales Department", "22", "Employee 1"));
        users.add(new User("Sales Department", "22", "Employee 2"));
        users.add(new User("Sales Department", "25", "Employee 4"));
        users.add(new User("Sales Department", "25", "Employee 5"));
        users.add(new User("IT Department", "42", "ID 2"));
        users.add(new User("HR Department", "22", "HR 1"));
        users.add(new User("HR Department", "22", "HR 2"));

        for (int i = 0; i < 40000; i++) {
            users.add(new User("HR Department", i % 10 + "", "HR 2" + i));
        }
        for (int i = 0; i < 40000; i++) {
            users.add(new User("Computer Department", i % 20 + "", "CD 2" + i));
        }

        for (int i = 0; i < 40000; i++) {
            users.add(new User("IT Department", i % 5 + "", "HR 2" + i));
        }

        // build tree
        final TreeItem<User> root = new RecursiveTreeItem<User>(users, RecursiveTreeObject::getChildren);

        JFXTreeTableView<User> treeView = new JFXTreeTableView<User>(root);
        treeView.setShowRoot(false);
        treeView.setEditable(true);
        treeView.getColumns().setAll(deptColumn, ageColumn, empColumn);

        JFXTextField filterField = new JFXTextField();
        filterField.textProperty().addListener((o, oldVal, newVal) -> {
            treeView.setPredicate(user -> user.getValue().age.get().contains(newVal)
                    || user.getValue().department.get().contains(newVal)
                    || user.getValue().userName.get().contains(newVal));
        });

        Label size = new Label();
        size.textProperty().bind(Bindings.createStringBinding(() -> treeView.getCurrentItemsCount() + "",
                treeView.currentItemsCountProperty()));

        AnchorPane an = new AnchorPane();
        an.getChildren().addAll(filterField, size, treeView);

        AnchorPane.setTopAnchor(treeView, 50d);
        AnchorPane.setLeftAnchor(filterField, 100d);

        Scene scene = new Scene(an);
        URL url = this.getClass().getResource("/css/myStyle.css");
        scene.getStylesheets().add(url.toExternalForm());
        primaryStage.setScene(scene);
        primaryStage.setWidth(800);
        primaryStage.setHeight(650);
        primaryStage.setTitle("JFoeniX测试");
        primaryStage.show();
    }
}
